Crypto Market Chart

Setting the Environment

In [1]:
!pip install -U yfinance
!pip install -U plotly
!pip install -U kaleido
Collecting yfinance
  Downloading yfinance-0.1.63.tar.gz (26 kB)
Requirement already satisfied: pandas>=0.24 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from yfinance) (1.2.4)
Requirement already satisfied: numpy>=1.15 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from yfinance) (1.19.2)
Requirement already satisfied: requests>=2.20 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from yfinance) (2.25.1)
Collecting multitasking>=0.0.7
  Downloading multitasking-0.0.9.tar.gz (8.1 kB)
Requirement already satisfied: lxml>=4.5.1 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from yfinance) (4.6.3)
Requirement already satisfied: python-dateutil>=2.7.3 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from pandas>=0.24->yfinance) (2.8.1)
Requirement already satisfied: pytz>=2017.3 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from pandas>=0.24->yfinance) (2021.1)
Requirement already satisfied: six>=1.5 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from python-dateutil>=2.7.3->pandas>=0.24->yfinance) (1.15.0)
Requirement already satisfied: idna<3,>=2.5 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from requests>=2.20->yfinance) (2.8)
Requirement already satisfied: certifi>=2017.4.17 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from requests>=2.20->yfinance) (2021.5.30)
Requirement already satisfied: chardet<5,>=3.0.2 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from requests>=2.20->yfinance) (3.0.4)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from requests>=2.20->yfinance) (1.26.6)
Building wheels for collected packages: yfinance, multitasking
  Building wheel for yfinance (setup.py) ... done
  Created wheel for yfinance: filename=yfinance-0.1.63-py2.py3-none-any.whl size=23907 sha256=72efdbaa9307cd2715d4be67b5444411324ca0a6ffd53c91b92f9762898c3eb4
  Stored in directory: /tmp/wsuser/.cache/pip/wheels/ec/cc/c1/32da8ee853d742d5d7cbd11ee04421222eb354672020b57297
  Building wheel for multitasking (setup.py) ... done
  Created wheel for multitasking: filename=multitasking-0.0.9-py3-none-any.whl size=8367 sha256=746bf5045d379536b0a42a79436f98948b42d68831572cd91b807f8bb15d204c
  Stored in directory: /tmp/wsuser/.cache/pip/wheels/57/6d/a3/a39b839cc75274d2acfb1c58bfead2f726c6577fe8c4723f13
Successfully built yfinance multitasking
Installing collected packages: multitasking, yfinance
Successfully installed multitasking-0.0.9 yfinance-0.1.63
Requirement already satisfied: plotly in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (4.14.3)
Collecting plotly
  Downloading plotly-5.1.0-py2.py3-none-any.whl (20.6 MB)
     |████████████████████████████████| 20.6 MB 18.6 MB/s eta 0:00:01
Requirement already satisfied: six in /opt/conda/envs/Python-3.8-main/lib/python3.8/site-packages (from plotly) (1.15.0)
Collecting tenacity>=6.2.0
  Downloading tenacity-8.0.1-py3-none-any.whl (24 kB)
Installing collected packages: tenacity, plotly
  Attempting uninstall: plotly
    Found existing installation: plotly 4.14.3
    Uninstalling plotly-4.14.3:
      Successfully uninstalled plotly-4.14.3
Successfully installed plotly-5.1.0 tenacity-8.0.1
Collecting kaleido
  Downloading kaleido-0.2.1-py2.py3-none-manylinux1_x86_64.whl (79.9 MB)
     |████████████████████████████████| 79.9 MB 68.9 MB/s eta 0:00:01
Installing collected packages: kaleido
Successfully installed kaleido-0.2.1
In [2]:
import numpy as np
import pandas as pd
import matplotlib
import random
import yfinance as yf
from plotly import graph_objs as go

Visualization Function

In [3]:
def get_crypto_visuals(coin, period="5d", interval="15m", MA=False, days=[7,25,99], boll=False, boll_sma=25, save_fig=False, img_format="png"):
  
  
  
  
  '''
  
  Utilizing Plotly and yfinance to make a Stock Market Coin-USD timeseries plot using Candlesticks
  
  
  
  Parameters
    -----------------
 
      coin: str
            
                - Symbol of Crypto coin i.e 'BTC', 'ETH', 'DOGE', 'BNB', 'SXP'
                - Must be currently listed on https://finance.yahoo.com/cryptocurrencies/
 
 
      period: str, Default "5d"
              
                - Answers the question - How far back from realtime should data be sourced?
                - Valid periods: '1d','5d','1mo','3mo','6mo','1y','2y','5y','10y','ytd','max'
 
 
      interval: str, Default "15m"
 
                - References intra-period intervals of data
                - Valid intervals: '1m','2m','5m','15m','30m','60m','90m','1h','1d','5d','1wk','1mo','3mo'
                - Intraday data cannot extend last 60 days
 
      
      MA: bool, Default False
           
                - References the plotting of the Moving Average (MA) data
      
 
      
      days: list, tuple, 1D array, Pandas Series, Set, Default = [7, 25, 99]
  
                - Must be an iterable containing integer values only
                - The integers represent, day subsets for the Moving Average data
            
 
      boll: bool, Default False
 
                - References the plotting of the bollinger band
                - Important: • When both MA and boll are True, MA takes preference
                             • The above algorithm is in place to avoid a rowdy chart
 
      boll_sma:   Integer, Default 25             
                  
                - Indicates the SMA value used as a reference point for plotting the bollinger band
      
      
      save_fig:   bool, Default False
                  
                - Saves the plot to the current working directory
      
 
      img_format: str, Default "png"
                - The desired image format:'png', 'jpg' or 'jpeg', 'webp', 'svg', and 'pdf'
      
 
  
  
  Returns
    -----------------
       None
       
  
  Examples
    -----------------
    >>> get_crypto_visuals("BTC")
    >>> get_crypto_visuals("BTC", MA=True)
    >>> get_crypto_visuals("BTC", period="10d", interval="5m", MA=True, days=[10,30,100], save_fig=True, img_format='jpeg')
    >>> get_crypto_visuals("BTC", period="10d", interval="5m", MA=False, days=[10,30,100], boll=True)
 
  '''
 
  #Error Handling
  if coin is None: raise ValueError("coin: Symbol of Crypto coin i.e 'BTC', 'ETH', 'DOGE', 'BNB', 'SXP'\nMust be currently listed on https://finance.yahoo.com/cryptocurrencies/")
  if not isinstance(period, str): raise TypeError('period: This parameter should be a string')
  if not isinstance(interval, str): raise TypeError('interval: This parameter should be a string')
  if not isinstance(img_format, str): raise TypeError('img_format: This parameter should be a string')
  if not isinstance(coin, str): raise TypeError('coin: This parameter should be a string')
  if not isinstance(MA, bool): raise TypeError('MA: This parameter should be boolean (True or False)')
  if not isinstance(boll, bool): raise TypeError('boll: This parameter should be boolean (True or False)')
  if not isinstance(save_fig, bool): raise TypeError('save_fig: This parameter should be boolean (True or False)')
  if not isinstance(boll_sma, int): raise TypeError('boll_sma: This parameter should be an Integer')
  if (not hasattr(days, '__iter__')) or isinstance(days, str): raise TypeError("days: This parameter should be iterable, strings aren't also allowed")
 
 
  
  
  
  coin = coin.upper().strip()
  data = yf.download(tickers=f'{coin}-USD',period = period, interval = interval)
  header = f"{coin}-USD Price Analysis"
  
 
  #Generate Moving Average
  if MA==True:
    for i in days: data[f'MA{i}'] = data['Close'].rolling(i).mean()
 
  
  #Generate Bollinger
  def get_bollinger_band(prices, rate=boll_sma):
    sma = prices.rolling(rate).mean()
    std = prices.rolling(rate).std()
    bollinger_up = sma + std * 2 
    bollinger_down = sma - std * 2
    return sma, bollinger_up, bollinger_down  
    
  if boll:
    if not (MA or (boll and MA)): sma, u,d = get_bollinger_band(data['Close'])
 
  #declare figure
  fig = go.Figure()
    
    
  #Candlestick
  fig.add_trace(go.Candlestick(x=data.index,
                               open=data['Open'],
                               high=data['High'],
                               low=data['Low'],
                               close=data['Close'], 
                               name = 'Market data'))
  #Randomly pick from preferred colors
  col_lst = ['pink','darkgray','orange','darkblue','darkcyan','darkgoldenrod','darkgray','darkgrey','darkkhaki','darkmagenta','darkorange','darkorchid','darksalmon','darkslateblue','darkslategray','darkslategrey','darkturquoise','darkviolet','deeppink']
  try: col_sam = random.sample(col_lst, len(days))
  except ValueError: col_sam = np.random.choice(col_lst, len(days))
  
  
  #Add Moving average on the chart
  co = 0
  for col in data.columns:
    if col.startswith('MA'):
      fig.add_trace(go.Scatter(x=data.index, y= data[col],line={'color':col_sam[co],'width':1.5}, name = col))
      co+=1
  
  #Add Bollinger on the chart
  if boll:
    if not (MA or (boll and MA)):
       fig.add_trace(go.Scatter(x=data.index, y= u,line={'color':'darkmagenta','width':1.5}, name = "BOLL (Up)"))
       fig.add_trace(go.Scatter(x=data.index, y=sma, line={'color':'orange','width':1.5}, name="BOLL (Mid)"))
       fig.add_trace(go.Scatter(x=data.index, y= d,line={'color':'darkblue','width':1.5}, name = "BOLL (Down)"))
  
  
  #Updating axis and graph
  fig.update_xaxes(title=f'Datetime', rangeslider_visible =True)
  
  fig.update_yaxes(title='USD ($)')
  fig.update_layout({"title": {"text": header}})
 
  #Show
  fig.show()
 
  #Save
  if save_fig: fig.write_image("fig_timeplot_{}-usd.{}".format(coin.lower(), img_format.lower()), engine='kaleido')

Examples

In [4]:
get_crypto_visuals('BTC')
[*********************100%***********************]  1 of 1 completed
In [5]:
get_crypto_visuals("BTC", MA=True)
[*********************100%***********************]  1 of 1 completed
In [6]:
get_crypto_visuals("BTC",
                   period="5d",
                   interval="15m",
                   MA=True,
                   days=[10,30,100],
                   save_fig=True)
[*********************100%***********************]  1 of 1 completed
In [7]:
get_crypto_visuals("BTC",
                   period="5d",
                   interval="15m",
                   boll=True,
                   boll_sma=26,
                   save_fig=True,
                   img_format='jpeg')
[*********************100%***********************]  1 of 1 completed